package com.bruce.tool.serialize.kryo;

import com.bruce.tool.serialize.core.SelfSerializable;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.util.Pool;

import java.util.Objects;

/**
 * 功能 :
 * 序列化-反序列化-线程安全
 * @author : Bruce(刘正航) 5:44 下午 2019/11/26
 */
public class KryoResolver implements SelfSerializable {

    private static Pool<Kryo> kryoPool = new Pool<Kryo>(true, false, 8) {
        @Override
        protected Kryo create() {
            Kryo kryo = new Kryo();
            kryo.setRegistrationRequired(false);
            kryo.setReferences(false);
            // Configure the Kryo instance.
            return kryo;
        }
    };
    private static Pool<Output> outputPool = new Pool<Output>(true, false, 16) {
        @Override
        protected Output create() {
            return new Output(2048, 4096);
        }
    };
    private static Pool<Input> inputPool = new Pool<Input>(true, false, 16) {
        @Override
        protected Input create() {
            return new Input(2048);
        }
    };

    @Override
    public byte[] serialize(Object data) {
        if(Objects.isNull(data)){
            return new byte[0];
        }
        Kryo kryo = kryoPool.obtain();
        Output output = outputPool.obtain();
        try {
            output.reset();
            kryo.writeObject(output, data);
            return output.getBuffer();
        } finally {
            kryoPool.free(kryo);
            outputPool.free(output);
        }
    }

    @Override
    public <T> T deserialize(byte[] bytes,Class<T> clazz) {
        if(Objects.isNull(bytes) || bytes.length == 0 || Objects.isNull(clazz)){
            return null;
        }
        Kryo kryo = kryoPool.obtain();
        Input input = inputPool.obtain();
        try {
            input.setBuffer(bytes);
            return kryo.readObject(input, clazz);
        } finally {
            kryoPool.free(kryo);
            inputPool.free(input);
        }
    }
}
